/**
 * @文件名 DateUtil.java
 * @包名 com.ykfk.cngrain.tbw.util
 * @说明  时间处理工具类
 * @作者 wdfang
 * @时间 2013-2-19 上午11:58:17
 * @版本 V1.0
 */ 
package com.fang.yttz.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Pattern;

import org.nutz.lang.Times;
/**
 * @类名 DateUtil
 * @描述  时间处理工具类
 * @作者 wdfang
 * @日期 2013-2-19 上午11:58:17
 * ========修改日志=======
 *
 */
public class DateUtil extends Times {
	/**
	 * 日期格式 默认：yyyy-MM-dd
	 */
	private static String pattern = "yyyy-MM-dd";
	/**
	 * 
	 * @名称 getDate
	 * @描述 根据预设的格式获得日期---年月日
	 * @参数 @param ptn 日期格式
	 * @参数 @return 年月日
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:05:11
	 */
	public static String getDate(String ptn) {
		Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
		SimpleDateFormat format = new SimpleDateFormat(ptn);
		Date date = calendar.getTime();
		return format.format(date);
	}
	/**
	 * 
	 * @名称 isBefore
	 * @描述 判断给定的两个日期的前后。strdate1在strdate2之前（或同一天），返回true，反之，false
	 * @参数 @param strdate1 日期1
	 * @参数 @param strdate2 日期2
	 * @参数 @return
	 * @返回值 boolean
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:24:55
	 */
	public static boolean isBefore(String strdate1, String strdate2) {
		Calendar cal1 = parseCalendar(strdate1);
		Calendar cal2 = parseCalendar(strdate2);
		return cal1.before(cal2);
	}
	/**
	 * 
	 * @名称 addByDay
	 * @描述 计算在当前系统日期增加或减少 n 天后的日期
	 * @参数 @param days 增加或减少的天数，正数增加，反之减少
	 * @参数 @return
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:24:38
	 */
	public static String addByDay(int days) {
		Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
		calendar.add(Calendar.DATE, days);
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		Date date = calendar.getTime();
		return format.format(date);
	}
	/**
	 * 
	 * @名称 addByDay
	 * @描述 计算在给定的日期加上或减去 n 天后的日期
	 * @参数 @param datestr 给定的日期
	 * @参数 @param days 正数增加，反之减少
	 * @参数 @return
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:23:56
	 */
	public static String addByDay(String datestr, int days) {
		Calendar cal = parseCalendar(datestr);
		cal.add(Calendar.DATE, days);
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		Date date = cal.getTime();
		return format.format(date);
	}
	/**
	 * 
	 * @名称 addByMonth
	 * @描述 在给定日期上加月加天 后的日期
	 * @参数 @param datestr
	 * @参数 @param months 增加月
	 * @参数 @param days 增加天
	 * @参数 @return
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:23:27
	 */
	public static String addByMonth(String datestr, int months, int days) {
		Calendar cal = parseCalendar(datestr);
		cal.add(Calendar.MONTH, months);
		cal.add(Calendar.DATE, days);
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		Date date = cal.getTime();
		return format.format(date);
	}
	/**
	 * 
	 * @名称 getDays
	 * @描述 获得给定日期与系统当前日期之间的天数
	 * @参数 @param strdate 给定的日期字符串
	 * @参数 @return
	 * @返回值 long 天数
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:22:38
	 */
	public static long getDays(String strdate) {
		Calendar cal = parseCalendar(strdate);
		Calendar cal1 = new GregorianCalendar(TimeZone.getDefault());
		long millis = Math.abs(cal.getTimeInMillis() - cal1.getTimeInMillis());
		return millis / (24 * 60 * 60 * 1000);
	}
	/**
	 * 
	 * @名称 getDaysBetween
	 * @描述 获得给定的两个日期之间相差的天数（日期不分前后）
	 * @参数 @param fromdate 日期字符串 格式：yyyymmdd
	 * @参数 @param todate 日期字符串 格式：yyyymmdd
	 * @参数 @return 
	 * @返回值 long
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:21:45
	 */
	public static long getDaysBetween(String fromdate, String todate) {
		Calendar from = parseCalendar(fromdate);
		Calendar to = parseCalendar(todate);
		long millis = Math.abs(from.getTimeInMillis() - to.getTimeInMillis());
		return millis / (24 * 60 * 60 * 1000);
	}
	/**
	 * 
	 * @名称 isDateStr
	 * @描述 判断字符串是否可以转换为日期型 是：true，否：false
	 * @参数 @param strdate 预转换字符串
	 * @参数 @return
	 * @返回值 boolean
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:17:43
	 */
	public static boolean isDateStr(String strdate) {
		if (strdate.length() != 8) {
			return false;
		}
		String reg = "^(\\d{4})((0([1-9]{1}))|(1[012]))((0[1-9]{1})|([1-2]([0-9]{1}))|(3[0|1]))$";
		if (Pattern.matches(reg, strdate)) {
			return getDaysOfMonth(strdate) >= Integer.parseInt(strdate.substring(6, 8));
		} else {
			return false;
		}
	}
	/**
	 * 
	 * @名称 isLeapYear
	 * @描述 判断是否是闰年（年限1000--9999）是：true，否：false
	 * @参数 @param strdate 预判断年 格式yyyymmdd 或 yyyy
	 * @参数 @return
	 * @返回值 boolean
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:16:09
	 */
	public static boolean isLeapYear(String strdate) {
		int y = Integer.parseInt(strdate.substring(0, 4));
		if (y <= 999) {
			return false;
		}
		if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 
	 * @名称 getDaysOfMonth
	 * @描述 获取某一月份的天数
	 * @参数 @param strdate 日期 格式：yyyymmdd 或 yyyymm
	 * @参数 @return
	 * @返回值 int
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:15:46
	 */
	public static int getDaysOfMonth(String strdate) {
		int m = Integer.parseInt(strdate.substring(4, 6));
		switch (m) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			return 31;
		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
		case 2:
			if (isLeapYear(strdate)) {
				return 29;
			} else {
				return 28;
			}
		default:
			return 0;
		}
	}
	/**
	 * 
	 * @名称 parseCalendar
	 * @描述 把字符串转换为Calendar
	 * @参数 @param strdate  预转换的字符串
	 * @参数 @return
	 * @返回值 Calendar
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:14:27
	 */
	private static Calendar parseCalendar(String strdate) {
		if (isDateStr(strdate)) {
			int year = Integer.parseInt(strdate.substring(0, 4));
			int month = Integer.parseInt(strdate.substring(4, 6)) - 1;
			int day = Integer.parseInt(strdate.substring(6, 8));
			return new GregorianCalendar(year, month, day);
		} else {
			return null;
		}
	}
	/**
	 * 
	 * @名称 getRepayDay
	 * @描述 查询下几个月的今天
	 * @参数 @param date 输入的期限
	 * @参数 @param val 要查询第几个月后的今天的日期
	 * @参数 @return 下几个月日期
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:12:20
	 */
	public static String getRepayDay(String date, int val) {
		int year = Integer.parseInt(date.substring(0, 4));
		int month = Integer.parseInt(date.substring(4, 6));
		int day = Integer.parseInt(date.substring(6, 8));
		String riqi = "";
		int reapyMonth = 0;
		if ((month + val) % 12 == 0) { // 如 月加上输入的月取模==0 则把初始化的月 赋值=12
			reapyMonth = 12;
		} else { // 否则把除以12 的余数赋值个月参数上
			reapyMonth = (month + val) % 12;
		}
		year += (month + val - 1) / 12; // 原先的月数+输入的要查询的月数 -1/12 如果和 是13 年加1
		if (reapyMonth <= 9) {
			riqi = year + "0" + reapyMonth + date.substring(6, 8);
		} else {
			riqi = year + "" + reapyMonth + date.substring(6, 8);
		}
		if (getDaysOfMonth(riqi) < day) { // 查询日期的日 < 当期日期的日 该日期 如 20090130 的
			// 下个月的期限是多少 ,日应该 是28, 因为不是闰年
			riqi = riqi.substring(0, 6) + DateUtil.getDaysOfMonth(riqi);// 这样
			// 就截取
			// 对应的日期加上
			// 该月应该有的日期是多少就对了,2,4,6,8
			// 等
			// 小月的日期就对了
		}
		return riqi;
	}
	/**
	 * 
	 * @名称 isBetween
	 * @描述 判断是否在开始日期和结束日期之间
	 * @参数 @param begin 开始日期 
	 * @参数 @param end 结束日期 
	 * @参数 @param betweenValue 中间值
	 * @参数 @param DateFormat 日期格式
	 * @参数 @param boundaryValue 是否包括边界值
	 * @参数 @return
	 * @返回值 boolean
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:10:02
	 */
	public static boolean isBetween(String begin, String end, String betweenValue, String DateFormat, boolean boundaryValue) {
		boolean flag = false;
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateFormat);
		try {
			Date beginDate = dateFormat.parse(begin);
			Date endDate = dateFormat.parse(end);
			Date betweenDate = dateFormat.parse(betweenValue);
			if (betweenDate.after(beginDate) && betweenDate.before(endDate)) {
				flag = true;
			}
			if (boundaryValue) {
				if (betweenDate.compareTo(beginDate) == 0) {
					flag = true;
				}
				if (betweenDate.compareTo(endDate) == 0) {
					flag = true;
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return flag;
	}
	/**
	 * 
	 * @名称 addDay
	 * @描述 给一个日期添加或减少几天
	 * @参数 @param tempdate 需要操作的日期变量
	 * @参数 @param days 需要添加几天，正数表示添加几天，负数表示减少几天
	 * @参数 @param format 日期格式
	 * @参数 @return
	 * @返回值 String
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:09:25
	 */
	public static String addDay(String tempdate, int days, String format) {
		int year = Integer.parseInt(tempdate.substring(0, 4));
		int month = 0;
		int day = 0;
		String s_month = tempdate.substring(4, 6);
		String s_day = tempdate.substring(6, 8);
		if ("0".equals(s_month.substring(0, 1))) {
			month = Integer.parseInt(tempdate.substring(5, 6));
		} else {
			month = Integer.parseInt(tempdate.substring(4, 6));
		}
		if ("0".equals(s_day.substring(0, 1))) {
			day = Integer.parseInt(tempdate.substring(7, 8));
		} else {
			day = Integer.parseInt(tempdate.substring(6, 8));
		}
		GregorianCalendar firstFlight = new GregorianCalendar(year, month - 1, day);
		DateFormat df = new SimpleDateFormat(format);
		Date date = firstFlight.getTime();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, days);
		return df.format(cal.getTime());
	}
	/**
	 * 
	 * @名称 getDays
	 * @描述 如果结束日期小余开始日期返回-1 相等返回0否则返回两个日期之间的天数
	 * @参数 @param begin 开始日期
	 * @参数 @param end 结束日期
	 * @参数 @param format 日期格式
	 * @参数 @return
	 * @返回值 long
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:08:53
	 */
	public static long getDays(String begin, String end, String format) {
		long datanumber = 0;
		SimpleDateFormat df = new SimpleDateFormat(format);
		long l_end;
		long l_begin;
		try {
			l_end = df.parse(end).getTime();
			l_begin = df.parse(begin).getTime();
			long temp = l_end - l_begin;
			datanumber = temp / (1000 * 60 * 60 * 24);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		if (datanumber < 0) {
			datanumber = -1;
		}
		return datanumber;
	}
	/**
	 * 
	 * @名称 isAfter
	 * @描述 判断end是不是在begin之后.是返回true不是返回false
	 * @参数 @param begin 开始日期
	 * @参数 @param end 结束日期
	 * @参数 @param format 日期格式
	 * @参数 @return
	 * @返回值 boolean
	 * @作者 wdfang
	 * @时间 2013-2-19 下午1:08:26
	 */
	public static boolean isAfter(String begin, String end, String format) {
		boolean flag = false;
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			Date beginDate = dateFormat.parse(begin);
			Date endDate = dateFormat.parse(end);
			flag = endDate.after(beginDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return flag;
	}
}
